home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************
- * MyMemMgr.c
- *
- * Optimized 68040 versions of BlockMove, NewPtrClear
- * and NewHandleClear.
- *
- * Mike Scanlin 8 Mar 1992
- ****************************************************/
-
- #include "MyMemMgr.h"
-
- /* Think C doesn't know this instruction:
- * Move16 (A0)+,(A1)+
- */
- #define Move16A0ToA1 DC.W 0xF620, 0x9000
-
- /* Move16BytesPerLoop must be a power of 2 and
- * agree with # of Move16 instructions per loop
- * in MyBlockMoveData
- */
- #define Move16BytesPerLoop 64
-
- /* LongBytesPerLoop must be a power of 2 and
- * agree with # of Move.L instructions per loop
- * in MyBlockMoveData
- */
- #define LongBytesPerLoop 16
-
- /* SmallNumBytes can't be less than 16 */
- #define SmallNumBytes 16
-
- /* ClearLongBytesPerLoop must be a power of 2 and
- * agree with # of Move.L instructions per loop
- * in MyNewPtrClear
- */
- #define ClearLongBytesPerLoop 64
-
- /* ClearBytesPerLoop must be a power of 2 and
- * agree with # of Move.L instructions per loop
- * in MyNewPtrClear
- */
- #define ClearBytesPerLoop 8
-
- /* gIn24BitMode needs to be set to TRUE if the
- * system is in 24-bit mode when you call
- * MyBlockMoveData; FALSE if in 32-bit mode
- */
- Boolean gIn24BitMode;
-
-
- /*****************************************************
- * MyBlockMoveData
- *
- * Equivalent to the system's BlockMove except that
- * it doesn't flush the 68040 data cache on exit so
- * it shouldn't be used to BlockMove code.
- ****************************************************/
- void
- MyBlockMoveData(const void *srcPtr, void *destPtr,
- Size byteCount)
- {
- asm {
-
- ;get parameters into registers
-
- Move.L srcPtr,D0
- Move.L destPtr,D1
- Move.L byteCount,D2
-
- ;if we're in 24-bit mode we need to StripAddress
- ;the addresses before comparison
-
- Tst.B gIn24BitMode
- Beq.S @1
- Andi.L #0x00FFFFFF,D0
- Andi.L #0x00FFFFFF,D1
-
- @1 Move.L D0,A0
- Move.L D1,A1
-
- ;if dst > src then we might need to move bytes
- ;last to first
-
- Cmp.L A0,A1
- Bhi.S @CheckForNonOverlapping
-
- ;if dst == src then we're done
-
- Beq.S @8
-
- MoveFrontToBack:
-
- ;if we're only doing a few bytes, skip the
- ;tricky stuff
-
- Cmp.L #SmallNumBytes,D2
- Bls.S @10
-
- ;if the low 4 bits of src and dst are equal
- ;then we can use Move16
-
- Andi #0x000F,D0
- Andi.L #0x0000000F,D1
- Cmp D0,D1
- Bne.S @ForwardLongLoop
- Tst D0
- Beq.S @4
-
- ;do the first few bytes at the beginning,
- ;until we're 16-byte aligned
-
- Eori #0x000F,D0 ;D0 = 16 - D0
- @2 Move.B (A0)+,(A1)+
- @3 Dbra D0,@2
- Sub.L D1,D2
-
- ;move groups of Move16BytesPerLoop bytes
-
- @4 Move.L D2,D1
- Andi.L #Move16BytesPerLoop-1,D2
- Sub.L D2,D1
- Beq.S @ForwardLongLoop
-
- Nop ;compensate for chip bug on some 040s
-
- @5 Move16A0ToA1
- Move16A0ToA1
- Move16A0ToA1
- Sub.L #Move16BytesPerLoop,D1
- Move16A0ToA1
- Bne.S @5
-
- ForwardLongLoop:
-
- ;move groups of LongBytesPerLoop bytes
-
- Move.L D2,D1
- Bra.S @7
-
- @6 Move.L (A0)+,(A1)+
- Move.L (A0)+,(A1)+
- Move.L (A0)+,(A1)+
- Move.L (A0)+,(A1)+
-
- @7 Sub.L #LongBytesPerLoop,D1
- Bpl.S @6
-
- ;move the last few remaining bytes
-
- Andi #LongBytesPerLoop-1,D2
- @8 Beq.S @Exit
- Subq #1,D2
- @9 Move.B (A0)+,(A1)+
- @10 Dbra D2,@9
-
- Bra.S @Exit
-
- CheckForNonOverlapping:
-
- ;if we're not overlapping, use the front-to-back
- ;loops so Move16 has a chance
-
- Sub.L A0,D1
- Cmp.L D1,D2
- Bhi.S @MoveBackToFront
- Move A1,D1
- Bra.S @MoveFrontToBack
-
- MoveBackToFront:
-
- ;set the pointers to one past the last byte
-
- Add.L D2,A0
- Add.L D2,A1
-
- ;if we're only doing a few bytes, skip the
- ;tricky stuff
-
- Cmp.L #SmallNumBytes,D2
- Bls.S @14
-
- ;move groups of LongBytesPerLoop/2 bytes
-
- Move.L D2,D1
- Bra.S @12
-
- @11 Move.L -(A0),-(A1)
- Move.L -(A0),-(A1)
-
- @12 Sub.L #LongBytesPerLoop/2,D1
- Bpl.S @11
-
- ;move the last few remaining bytes
-
- Andi #(LongBytesPerLoop/2)-1,D2
- Beq.S @Exit
- Subq #1,D2
- @13 Move.B -(A0),-(A1)
- @14 Dbra D2,@13
-
- Exit:
-
- }
- }
-
-
- /* Declare extra entry points so that functions
- * can share the memory clearing code.
- */
- void ClearHandleBytes(void);
- void ClearPtrBytes(void);
- void ClearBytes(void);
-
- /*****************************************************
- * MyNewHandleClear
- *
- * Faster version of the system's NewHandleClear.
- ****************************************************/
- Handle
- MyNewHandleClear(Size theSize)
- {
- register Handle h;
-
- if (h = NewHandle(theSize)) {
-
- asm {
- Bra ClearHandleBytes;
- }
- }
-
- return (h);
- }
-
-
- /*****************************************************
- * MyNewHandleSysClear
- *
- * Faster version of the system's NewHandleSysClear.
- ****************************************************/
- Handle
- MyNewHandleSysClear(Size theSize)
- {
- register Handle h;
-
- if (h = NewHandleSys(theSize)) {
-
- asm {
-
- extern ClearHandleBytes:
-
- Move.L h,A0
- Move.L (A0),A0
- Bra ClearBytes
- }
- }
-
- return (h);
- }
-
-
- /*****************************************************
- * MyNewPtrSysClear
- *
- * Faster version of the system's NewPtrSysClear.
- ****************************************************/
- Ptr
- MyNewPtrSysClear(Size theSize)
- {
- register Ptr p;
-
- if (p = NewPtrSys(theSize)) {
-
- asm {
- Bra ClearPtrBytes
- }
- }
-
- return (p);
- }
-
-
- /*****************************************************
- * MyNewPtrClear
- *
- * Faster version of the system's NewPtrClear.
- ****************************************************/
- Ptr
- MyNewPtrClear(Size theSize)
- {
- register Ptr p;
-
- if (p = NewPtr(theSize)) {
-
- asm {
-
- extern ClearPtrBytes:
-
- Move.L p,A0
-
- extern ClearBytes:
-
- ;init bytesUntilDone
-
- Move.L theSize,D2
-
- ;init the seed value
-
- Moveq #0,D0
-
- ;clear groups of ClearLongBytesPerLoop bytes
-
- Move.L D2,D1
- Bra.S @2
-
- @1 Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
- Move.L D0,(A0)+
-
- @2 Sub.L #ClearLongBytesPerLoop,D1
- Bpl.S @1
-
- ;clear groups of ClearBytesPerLoop bytes
-
- Andi #ClearLongBytesPerLoop-1,D2
- Move D2,D1
- Bra.S @4
-
- @3 Move.L D0,(A0)+
- Move.L D0,(A0)+
-
- @4 Subq #ClearBytesPerLoop,D1
- Bpl.S @3
-
- ;clear the last few remaining bytes
-
- Andi #ClearBytesPerLoop-1,D2
- Beq.S @Exit
- Subq #1,D2
- @5 Move.B D0,(A0)+
- Dbra D2,@5
-
- Exit:
-
- }
- }
-
- return (p);
- }
-